#pragma once

#include "Message.h"
#include "MessageBase.h"
#include <vector>
#include <boost/shared_ptr.hpp>
#include "FlightInfoFwd.h"
#include "FlightInfo.h"


class AbstractMessageFactory
{
public:
   AbstractMessageFactory(void);
   virtual ~AbstractMessageFactory(void);
   MessageBasePtr ParseMessage(const Message&);
protected:
   typedef std::vector< std::string > split_vector_type;
   typedef split_vector_type::iterator split_vector_type_iter;
   virtual MessageBasePtr do_parseMessage(MessagesEnum, split_vector_type_iter, split_vector_type_iter) = 0;
};

template<typename Iter>
FlightInfoPtr ParseShipsLaunched(Iter begin, Iter end)
{
   FlightInfoPtr flightInfoPtr = boost::make_shared<FlightInfo>();
   if (*begin++ != "SrcPlanets")
   {
      throw std::exception("MessageFactory::buildShipsLaunchedMessage wrong message");
   }

   PlanetID currentPlanetID;
   unsigned int countOfShips;

   do 
   {
      currentPlanetID = PlanetID(atoi((begin++)->c_str()));
      countOfShips = unsigned(atoi((begin++)->c_str()));
      flightInfoPtr->AddSrcPlanet(PlanetShipsCountPair(currentPlanetID, countOfShips));
   } while (*begin != "DstPlanet" && begin != end);

   begin++;

   PlanetID planetID = PlanetID(atoi((begin++)->c_str()));

   flightInfoPtr->SetDstPlanetID(planetID);

   if (begin != end)
   {
      throw std::exception("MessageFactory::buildShipsLaunchedMessage wrong message(begin != end)");
   }

   return flightInfoPtr;
}

typedef boost::shared_ptr<AbstractMessageFactory> AbstractMessageFactoryPtr;